package com.mh.framework.security.service;

import com.mh.common.utils.ServletUtils;
import com.mh.system.domain.LoginUserDetails;
import com.mh.system.domain.SysRole;
import com.mh.system.service.TokenService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Set;

//自定义权限校验类
@Component("MyPermsCheck")
public class PermsCheckService {

    //定义admin管理员的常量
    private static final String ALL_PERMISSIONS = "*:*:*"; //表示全部权限

    @Autowired
    private TokenService tokenService;

    //方法1: 权限校验
    //@PreAuthorize("hasAuthority('system:user:list')") Controller调用,传入一个权限
    public boolean checkPerm(String perm) {
        //如果是空, 则返回false
        if (StringUtils.isEmpty(perm)){
            return false;
        }

        LoginUserDetails loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        //如果获取的LoginUser为空,或者权限集合为空, 则返回false
        if (loginUser == null || CollectionUtils.isEmpty(loginUser.getPermissions())){
            return false;
        }
        //调用下面的"判断权限"方法, 传入LoginUser的权限集合 & 传入的权限
        return hasPerms(loginUser.getPermissions(),perm);
    }
    //权限集合中是否有指定权限, 传入权限集合 & 权限
    private boolean hasPerms(Set<String> perms, String perm) {

        //Set集合的方法.contains()-->前面的是否包含后面的, 返回true/false
        //判断权限集合中是否包含()内权限 或者 权限集合中是否有"*:*:*"权限(表示admin)
        return perms.contains(perm) || perms.contains(ALL_PERMISSIONS);

    }
    //验证用户是否有任意一个权限
    //@PreAuthorize("hasAnyAuthority('system:user:list,system:role:list')")
    //Controller传入多个权限,String类型,用","隔开
    public boolean hasAnyPerms(String perms) {
        //如果是空, 则返回false
        if (StringUtils.isEmpty(perms)){
            return false;
        }

        LoginUserDetails loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        //如果获取的LoginUser为空,或者权限集合为空, 则返回false
        if (loginUser == null || CollectionUtils.isEmpty(loginUser.getPermissions())){
            return false;
        }

        //获取loginUser对象的权限集合
        Set<String> userPerms = loginUser.getPermissions();

        //对传入的String遍历-->多个权限用","隔开, 获取新的权限String数组
        for (String permArray : perms.split(",")){
            //遍历的权限数组非空 & loginUser权限中包含遍历的权限数组 --> 返回true
            if (StringUtils.isEmpty(permArray) && hasPerms(userPerms,permArray)){ //调用上面的集合权限判断方法
                return true;
            }
        }
        return false;
    }

    //方法2: 角色校验
    public boolean checkRole(String role) {
        //如果是空, 则返回false
        if (StringUtils.isEmpty(role)){
            return false;
        }

        LoginUserDetails loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        List<SysRole> userRoles = loginUser.getUser().getRoles();

        //如果获取的LoginUser为空,或者角色合为空, 则返回false
        if (loginUser == null || CollectionUtils.isEmpty(userRoles)){
            return false;
        }

        //数据库中查出的用户角色遍历
        for (SysRole userRole : userRoles){
            //数据库中roleKey: admin,common,service
            String roleKey = userRole.getRoleKey();
            //如果roleKey为admin 或者 roleKey=传入的role --> 表示有角色,返回true
            if("admin".equals(roleKey) || roleKey.equals(role)){
                return true;
            }
        }
        return false;
    }
    //验证用户是否有任意一个角色
    public boolean hasAnyRoles(String roles) {
        //如果是空, 则返回false
        if (StringUtils.isEmpty(roles)){
            return false;
        }

        LoginUserDetails loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        //如果获取的LoginUser为空,或者权限集合为空, 则返回false
        if (loginUser == null || CollectionUtils.isEmpty(loginUser.getPermissions())){
            return false;
        }

        //对传入的String遍历-->多个角色用","隔开, 获取新的角色String数组
        for (String rolesArray : roles.split(",")){
            if (checkRole(rolesArray)){ //调用上面的角色判断方法
                return true;
            }
        }
        return false;
    }
}
